﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using Wizard.WizardControl;
using Wizard.CoffeeModel;
using Wizard.CoffeeView;
using Wizard.WizardControl.Models;
using Wizard.WizardControl.Views;
using Wizard.BranchTestModel;
using Wizard.BranchTestView;
using System.ComponentModel;
using System.Windows.Input;

namespace Wizard
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {

        public IWizardViewModel WizardVM
        {
            get { return (IWizardViewModel)GetValue( WizardVMProperty ); }
            set { SetValue( WizardVMProperty, value ); }
        }
        public static readonly DependencyProperty WizardVMProperty = DependencyProperty.Register( "WizardVM", typeof( IWizardViewModel ), typeof( MainWindow ) );

        private readonly WizardView CoffeeWizardView;
        private readonly WizardView RouteChangingWizardView;
        public event PropertyChangedEventHandler PropertyChanged;

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            CoffeeWizardView = GetPlainWizardView();
            RouteChangingWizardView = GetRouteChangingWizardView();
        }

        private void Plain_Click( object sender, RoutedEventArgs e )
        {
            wizardHost.Children.Clear();
            wizardHost.Children.Add( CoffeeWizardView );
            FirePropsChanged( CoffeeWizardView.DataContext as IWizardViewModel );
        }

        private void RouteChanging_Click( object sender, RoutedEventArgs e )
        {
            wizardHost.Children.Clear();
            wizardHost.Children.Add( RouteChangingWizardView );
            FirePropsChanged( RouteChangingWizardView.DataContext as IWizardViewModel );
        }

        private void FirePropsChanged( IWizardViewModel wizardViewModel )
        {
            WizardVM = wizardViewModel;
            OnPropertyChanged( "WizardVM" );
        }

        private static WizardView GetPlainWizardView()
        {
            /// 1)
            /// Create a WizardViewModel passing the type of the object the wizard will model.
            /// The type it's modeling must have parameterless constructor; WizardViewModel will create it.
            var wizModel = new WizardViewModel<CupOfCoffee>();

            /// 2)
            /// Create / provide the steps for the wizard.  See comments in the CreateSteps method.
            wizModel.ProvideSteps( CreateCoffeeSteps( wizModel.BusinessObject ) );

            /// 3)
            /// Create the actual wizard view / control.  Set it's DataContext to the WizardViewModel object created above.
            return new WizardView() { Height = 400, Width = 600, DataContext = wizModel };
        }

        private static WizardView GetRouteChangingWizardView()
        {
            var wizModel = new WizardViewModel<BranchTest>();
            wizModel.ProvideSteps( CreateRouteChangingSteps( wizModel.BusinessObject ) );
            return new WizardView() { Height = 400, Width = 600, DataContext = wizModel };
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cupOfCoffee">This is the instance created by the WizardViewModel</param>
        /// <returns></returns>
        private static List<CompleteStep<CupOfCoffee>> CreateCoffeeSteps( CupOfCoffee cupOfCoffee )
        {
            /// 2.1) Create a view model for each step.
            ///     Each of these descend from WizardStepViewModelBase
            var step1ViewModel = new WelcomeStepViewModel( cupOfCoffee );
            /// This ViewModel contains a RouteOptionGroupViewModel (a group of options that may alter the workflow of the wizard).
            /// See TypeSizeStepViewModel.CreateAvailableDrinkSizes.
            var step2ViewModel = new TypeSizeStepViewModel( cupOfCoffee );
            var step3ViewModel = new ExtrasStepViewModel( cupOfCoffee );
            var step4ViewModel = new SummaryStepViewModel(  cupOfCoffee,
                                                            step2ViewModel.AvailableBeanTypes,
                                                            step2ViewModel.AvailableDrinkSizes,
                                                            step3ViewModel.AvailableFlavorings,
                                                            step3ViewModel.AvailableTemperatures );

            /// 2.2) Create a list of steps.
            ///     We pass the same type param (CupOfCoffee) that we passed to WizardViewModel in Button_Click above.
            return new List<CompleteStep<CupOfCoffee>>() 
            {
                /// Each step contains a ViewModel and a View type (the type representing the actual Xaml to be shown).
                new CompleteStep<CupOfCoffee>() { ViewModel = step1ViewModel, ViewType = typeof(WelcomePageView), Visited = true },
                new CompleteStep<CupOfCoffee>() { ViewModel = step2ViewModel, ViewType = typeof(CoffeeTypeSizePageView) },
                new CompleteStep<CupOfCoffee>() { ViewModel = step3ViewModel, ViewType = typeof(CoffeeExtrasPageView) },
                new CompleteStep<CupOfCoffee>() { ViewModel = step4ViewModel, ViewType = typeof(CoffeeSummaryPageView) }
            };
        }

        private static List<CompleteStep<BranchTest>> CreateRouteChangingSteps( BranchTest o )
        {
            var step1ViewModel = new Step1Model( o );
            var step2ViewModel = new Step2Model( o );
            var step3ViewModel = new Step3Model( o );
            var step4ViewModel = new FinishModel( o );

            return new List<CompleteStep<BranchTest>>() 
            {
                /// Each step contains a ViewModel and a View type (the type representing the actual Xaml to be shown).
                new CompleteStep<BranchTest>() { ViewModel = step1ViewModel, ViewType = typeof(Step1), Visited = true },
                new CompleteStep<BranchTest>() { ViewModel = step2ViewModel, ViewType = typeof(Step2) },
                new CompleteStep<BranchTest>() { ViewModel = step3ViewModel, ViewType = typeof(Step3) },
                new CompleteStep<BranchTest>() { ViewModel = step4ViewModel, ViewType = typeof(Finish) }
            };
        }

        private void Finish_Click( object sender, RoutedEventArgs e )
        {
            if ( WizardVM == null )
            {
                MessageBox.Show( "OK, the enabling of this button is not really working unless a wizard is created" );
            }
            else
            {
                dynamic bo = ( (dynamic)( (FrameworkElement)wizardHost.Children[0] ).DataContext ).BusinessObject;
                MessageBox.Show( string.Format( "Do something with your [{0}] object.", bo ) );
            }
        }

        protected void OnPropertyChanged( string name )
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if ( handler != null )
            {
                handler( this, new PropertyChangedEventArgs( name ) );
            }
        }

    }
}
